//
//  Dispatcher.m
//  Cidney
//
//  Created by Chris Karr on 1/8/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//

#import "Dispatcher.h"
#import "Caller.h"
#import <AddressBook/AddressBook.h>

@implementation Dispatcher

@synthesize lastCall;
@synthesize clearTimer;
@synthesize ringTimer;

- (void) ring
{
	if (self.ringTimer != nil)
	{
		[self.ringTimer invalidate];
		self.ringTimer = nil;
	}
	
	if (self.ringTimer != nil)
		[self.ringTimer invalidate];
		
	self.ringTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(postCall:) userInfo:self.lastCall repeats:NO];
}

- (void) postCall:(NSTimer *) timer
{
	[[NSNotificationCenter defaultCenter] postNotificationName:INCOMING_CALL object:self userInfo:[timer userInfo]];
}

- (NSString *) normalizePhoneNumber:(NSString *) number
{
	NSMutableString * newNumber = [NSMutableString stringWithString:number];
	
	[newNumber replaceOccurrencesOfString:@"\r" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange (0, [newNumber length])];
	[newNumber replaceOccurrencesOfString:@"\n" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange (0, [newNumber length])];
	[newNumber replaceOccurrencesOfString:@"-" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange (0, [newNumber length])];
	[newNumber replaceOccurrencesOfString:@" " withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange (0, [newNumber length])];
	[newNumber replaceOccurrencesOfString:@"(" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange (0, [newNumber length])];
	[newNumber replaceOccurrencesOfString:@")" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange (0, [newNumber length])];
	[newNumber replaceOccurrencesOfString:@"+" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange (0, [newNumber length])];
	
	return newNumber;
}

- (ABPerson *) findPersonByNumber:(NSString *) number
{
	number = [self normalizePhoneNumber:number];
	
	ABAddressBook * ab = [ABAddressBook sharedAddressBook];
				
	for (ABPerson * person in [ab people])
	{
		ABMutableMultiValue * phones = [person valueForProperty:kABPhoneProperty];
		
		int i = 0;
		for (i = 0; i < [phones count]; i++)
		{
			NSString * phone = [self normalizePhoneNumber:[phones valueAtIndex:i]];
		
			if ([phone rangeOfString:number].location != NSNotFound)
				return person;
		}
	}
	
	return nil;
}

- (void) awakeFromNib
{
	self.lastCall = [NSMutableDictionary dictionary];
	self.clearTimer = nil;
	
	[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(process:) name:DATA_RECEIVED object:nil];
}

- (void) process:(NSNotification *) note
{
	[self.lastCall setValue:[NSDate date] forKey:TIME_KEY];
	
	NSDictionary * userInfo = [note userInfo];
	
	NSString * dataString = [[userInfo valueForKey:DATA_STRING] stringByReplacingOccurrencesOfString:@"\r" 
																						  withString:@"\n"];

	for (NSString * line in [dataString componentsSeparatedByString:@"\n"])
	{
		if (![line isEqualToString:@""])
		{
			if ([line hasPrefix:@"RING"])
			{
				if ([self.lastCall valueForKey:NAME_KEY] == nil)
					[self.lastCall setValue:@"Unknown Caller" forKey:NAME_KEY];

				if ([self.lastCall valueForKey:NUMBER_KEY] == nil)
					[self.lastCall setValue:@"Unknown Number" forKey:NUMBER_KEY];
				
				[self ring];
			}
			else if ([line rangeOfString:@" = "].location != NSNotFound)
			{
				NSArray * tokens = [line componentsSeparatedByString:@" = "];
				
				NSString * key = [tokens objectAtIndex:0];
				NSString * value = [tokens objectAtIndex:1];
				
				if ([key isEqualToString:@"NAME"])
					[self.lastCall setValue:value forKey:NAME_KEY];
				else if ([key isEqualToString:@"NMBR"])
				{
					[self.lastCall setValue:[self normalizePhoneNumber:value] forKey:NUMBER_KEY];
					
					ABPerson * person = [self findPersonByNumber:value];

					if (person != nil)
						[self.lastCall setValue:person forKey:PERSON_KEY];
				}

				[self ring];
			}
			else if ([line hasPrefix:@"NO DIALTONE"])
				[[NSNotificationCenter defaultCenter] postNotificationName:OFF_HOOK object:self];
		}
	}
	
	if (self.clearTimer != nil)
	{
		[self.clearTimer invalidate];
		self.clearTimer = nil;
	}
		
	self.clearTimer = [NSTimer scheduledTimerWithTimeInterval:15 target:self selector:@selector(reset:) userInfo:nil repeats:NO];
}

- (void) reset:(NSTimer *) theTimer
{
	self.lastCall = [Caller dictionary];
	
	self.clearTimer = nil;
}

@end
